package com.xiamo.controller;

import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.JsonObject;
import com.itextpdf.text.pdf.PdfPTable;
import com.xiamo.common.AjaxResult;
import com.xiamo.entity.BillRecord;
import com.xiamo.entity.WxUser;
import com.xiamo.mapper.WxUserMapper;
import com.xiamo.security.SecurityService;
import com.xiamo.service.IBillRecordService;
import com.xiamo.service.IRequestHistoryService;
import com.xiamo.service.IWxUserService;
import com.xiamo.service.impl.WxUserServiceImpl;
import com.xiamo.utils.GeminiUtil;
import com.xiamo.utils.OpenAiUtil;
import com.xiamo.utils.pdf.PDFUtil;
import com.xiamo.vo.BillRequestVo;
import com.xiamo.vo.OpenAiMessageBody;
import com.xiamo.vo.OpenAiRequest;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * The type Bill controller.
 *
 * @Author: AceXiamo
 * @ClassName: BillController
 * @Date: 2023 /7/3 16:39
 */
@RestController
@RequestMapping("bill")
public class BillController {
    private static final String ROOT_PATH = System.getProperty("user.dir");
    /**
     * The Bill record service.
     */
    @Autowired
    private IBillRecordService billRecordService;

    /**
     * The Request history service.
     */
    @Autowired
    private IRequestHistoryService requestHistoryService;

    @Autowired
    private SecurityService securityService;

    @Autowired
    private IWxUserService wxUserService;

    /**
     * List for month ajax result.
     *
     * @param month the month
     * @return the ajax result
     */
    @PostMapping("listForMonth")
    public AjaxResult listForMonth(@RequestParam(name = "month") String month) {
        return AjaxResult.success(billRecordService.listForMonth(month));
    }

    /**
     * Today data ajax result.
     *
     * @return the ajax result
     */
    @PostMapping("todayData")
    public AjaxResult todayData() {
        return AjaxResult.success(billRecordService.todayData());
    }

    /**
     * Save ajax result.
     *
     * @param data the data
     * @return the ajax result
     */
    @PostMapping("save")
    public AjaxResult save(@RequestBody BillRequestVo data) {
        BillRecord record = new BillRecord();
        record.setId(IdUtil.objectId());
        DateTime now = new DateTime();
        if (data.getDay().equals(DateUtil.format(now, "yyyy-MM-dd"))) {
            record.setRecordTime(now);
        } else {
            record.setRecordTime(DateUtil.parse(data.getDay(), "yyyy-MM-dd"));
        }
        //新增文字审核
        String accessToken = securityService.accessToken();

        JSONObject datas = new JSONObject();
        datas.put("content",data.getChat());
        RestTemplate restTemplate = new RestTemplate();
        String url = ("https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + accessToken);

        String response = restTemplate.postForObject(url, datas, String.class);
        JSONObject json = JSONObject.parseObject(response);

        GeminiUtil.Result res = GeminiUtil.say(data.getChat(), data.getHasAiSay());
        requestHistoryService.saveReqHis(Objects.requireNonNull(SecurityService.getWxUser()).getOpenId(), res.getBody(), JSON.toJSONString(res));

        String jsonText = res.getText();
        List<BillRecord> billRecords = new ArrayList<>();
        int startIndex = 0;
        while (startIndex < jsonText.length()) {
            int endIndex = jsonText.indexOf("}", startIndex) + 1;
            String jsonRecord = jsonText.substring(startIndex, endIndex);
            JSONObject jsonObject = JSON.parseObject(jsonRecord);
            if(jsonObject == null){
                return AjaxResult.error( "呃呃，你输入的语言我听不懂");
            }
            BillRecord billRecord = JSON.parseObject(jsonObject.toJSONString(), BillRecord.class);

            BillRecord newRecord = new BillRecord();
            newRecord.setId(IdUtil.objectId());
            newRecord.setRecordTime(record.getRecordTime());
            BeanUtil.copyProperties(billRecord, newRecord, CopyOptions.create().ignoreNullValue());
            newRecord.setOpenId(SecurityService.getWxUser().getOpenId());
            newRecord.setImages(JSON.toJSONString(data.getImages()));
            billRecords.add(newRecord);
            startIndex = endIndex;
        }

        for (BillRecord billRecord : billRecords) {
            billRecordService.save(billRecord);
        }

        return AjaxResult.success(billRecords);
    }


    /**
     * Update ajax result.
     *
     * @param record the record
     * @return the ajax result
     */
    @PostMapping("update")
    public AjaxResult update(@RequestBody BillRecord record) {
        record.setUpdateTime(new DateTime());
        billRecordService.updateById(record);
        return AjaxResult.success();
    }

    /**
     * Delete ajax result.
     *
     * @param id the id
     * @return the ajax result
     */
    @PostMapping("del")
    public AjaxResult delete(@RequestParam(name = "id") String id) {
        billRecordService.removeById(id);
        return AjaxResult.success();
    }

    /**
     * Statistics ajax result.
     *
     * @param date the date
     * @return the ajax result
     */
    @PostMapping("statistics")
    public AjaxResult statistics(@RequestParam(name = "date") String date) {
        return AjaxResult.success(billRecordService.statistics(date));
    }
    /**
     * @Description:  重置账单（清空全部）
     * @return: AjaxResult
     * @Author: dawu
     * @Date: 2024-04-09 18:24
     */
    @PostMapping("reset")
    public AjaxResult reset(@RequestBody BillRecord dto){

        return AjaxResult.success(billRecordService.remove(Wrappers.<BillRecord>lambdaQuery()
        .eq(BillRecord::getOpenId,dto.getOpenId())));
    }


    /**
     * @Description:  导出PDF账单
     * @return:
     * @Author: dawu
     * @Date: 2024-04-09 23:09
     */
    @PostMapping("exportBillPdf")
    public AjaxResult exportBillPdf(@RequestBody BillRecord dto) throws Exception {
        WxUser user = wxUserService.getOne(Wrappers.<WxUser>lambdaQuery()
        .eq(WxUser::getOpenId,dto.getOpenId()));
        List<BillRecord> list = billRecordService.list(Wrappers.<BillRecord>lambdaQuery()
                .eq(BillRecord::getOpenId, dto.getOpenId()));

        // 生成pdf数据
        List<String> header = new ArrayList<String>();
        PdfPTable table = PDFUtil.createTable(7);
        header.add("id");
        table.addCell(PDFUtil.createCell_1("id"));

        header.add("remark");
        table.addCell(PDFUtil.createCell_1("记账信息"));
        header.add("price");
        table.addCell(PDFUtil.createCell_1("金额"));
        header.add("record_type");
        table.addCell(PDFUtil.createCell_1("类型"));
        header.add("ai_say");
        table.addCell(PDFUtil.createCell_1("ai的吐槽"));
        header.add("record_time");
        table.addCell(PDFUtil.createCell_1("记录时间"));

        header.add("type_name");
        table.addCell(PDFUtil.createCell_1("分类名称"));

        if (list != null && list.size() > 0) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (BillRecord record : list) {
                table.addCell(PDFUtil.createCell_1(record.getId()));
                table.addCell(PDFUtil.createCell_1(record.getRemark()));

                String price = record.getPrice().toString();
                if (record.getRecordType() == 0) {
                    price = "-" + price;
                } else {
                    price = "+" + price;
                }
                table.addCell(PDFUtil.createCell_1(price));
                table.addCell(PDFUtil.createCell_1(record.getRecordType() == 0 ? "支出" : "收入"));
                table.addCell(PDFUtil.createCell_1(record.getAiSay()));
                table.addCell(PDFUtil.createCell_1(dateFormat.format(record.getRecordTime())));
                table.addCell(PDFUtil.createCell_1(record.getTypeName()));
            }
        }

        String output = ROOT_PATH +"/file/" + "账单明细导出" + new SimpleDateFormat("mmsss").format(new Date()) + ".pdf";
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(output)));

        PDFUtil.exportPdf(out, table, "账单明细");

        out.close();

        // 邮件服务器的配置信息
        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.qq.com"); // 邮件服务器主机名
        properties.put("mail.smtp.port", "587"); // 邮件服务器端口号
        properties.put("mail.smtp.auth", "true"); // 启用身份验证

        // 邮件发送者的账号和密码
        final String username = "1375490651@qq.com";
        final String password = "tkrwoyaqvbsajbgc";

        // 创建会话对象
        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

        if(StringUtils.isEmpty(user.getEmail())){
            return AjaxResult.error("未完善邮箱，请前往个人资料补充！");
        }
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress("1375490651@qq.com"));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail()));
        message.setSubject("账单报表");

        MimeBodyPart attachmentPart = new MimeBodyPart();
        attachmentPart.attachFile(new File(output));

        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(attachmentPart);

        message.setContent(multipart);

        Transport.send(message);

        // 返回结果
        return AjaxResult.success();
    }


}
